home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Sound Fx
/
Sound Fx.iso
/
Software
/
UNZIPED
/
SBPLY254
/
SOURCE.ZIP
/
SB.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-04
|
11KB
|
499 lines
/***************************************************************************/
/* sb.c -- Routines Sound Blaster Card & DIGPak Drivers */
/* Copyright (c) 1995 John A. Ball */
/* */
/* This source is available for your own personal use only! You may make */
/* any changes you wish but please do not distribute modified source code. */
/* Please notify me of any errors or improvements. */
/* */
/* by John A. Ball July 4, 1996 */
/***************************************************************************/
#include <stdio.h>
#include <dos.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include <malloc.h>
#include <string.h>
#include <sound.h>
#include <graph.h>
#define SB_ADDRESS 0x210 /* starting i/o address for SB */
#define TRUE 1
#define NOCOMPRESS 100
struct SNDSTRUC snd;
extern int debug;
extern int verbose;
extern int shell;
extern int sb_info;
extern struct CARD_INFO card_info;
extern int volume;
extern int compression;
extern int magnitude;
extern int default_bits;
extern int stop;
extern int repeat;
extern int error;
extern int multi_error;
extern int conversion_table;
extern unsigned int play_rate;
extern unsigned int pitch;
extern char _far **fbuffer;
extern unsigned int dma_size;
int sb_address=0;
int *psb;
int sb_card(void);
int find_sb(void);
int get_sb_info(void);
int reset_sb(int address);
void show_card_info(void);
int speaker(int state);
void delay(char tc, int period);
int dacplay(char _far *fbuffer,int k,int frequency,int mode,int volume,int channels);
int digplay(struct SNDSTRUC _far *sndplay);
void show_dac_error(int error);
int find_digpak(void);
int get_card_type(void);
int get_version(void);
int play_block(struct SOUND *hp, int source_handle);
int sb_card(void)
{
int error=0;
int blaster=0;
psb=&sb_info;
error=get_sb_info();
blaster=psb[4];
if(error > 0){
printf("Error in Sound Blaster Environment %i\n",error);
switch(error)
{
case 10:
printf("A (Address ie A220) Parameter not found!\n");
break;
case 20:
printf("I (Irq ie I5) Parameter not found!\n");
break;
case 30:
printf("D (DMA ie D1) Parameter not found!\n");
break;
case 40:
printf("T (Type ie T3) Parameter not found!\n");
break;
}
blaster=find_sb();
}
else{
if((error < 0) && debug)
printf("No BLASTER parameters found in environment\n");
if(error < 0){
blaster=find_sb();
}
if(!error){
error=reset_sb(blaster);
if(error){
blaster=find_sb();
printf("Environment BLASTER=A (Address) parameter is not correct.\n");
}
}
if(blaster){
psb[4]=blaster;
}
}
if(blaster){
if(reset_sb(blaster))
printf("Sound Blaster not responding to reset!\n");
card_info.io_addr=blaster;
sb_address=blaster;
}
return(blaster);
}
/* Make sure Sound Blaster Available */
int find_sb(void)
{
int blaster=0;
_asm{
push bx
mov bx,0
h0:
mov al,1
mov dx,SB_ADDRESS
add dx,6
add dx,bx
out dx,al
in al,dx
in al,dx
in al,dx
in al,dx
mov al,0
out dx,al
add dx,4
mov cx,0ffffh
h1:
in al,dx
cmp al,0aah
je h2
loop h1
add bx,010h
cmp bx,050h
jle h0
mov ax,0
mov blaster,ax
jmp h3
h2:
mov ax,SB_ADDRESS
add ax,bx
mov blaster,ax
h3: pop bx
}
if(debug && blaster)printf("Found Sound Blaster Board @ %x\n",blaster);
return(blaster);
}
int get_sb_info(void)
{
char *pe;
char v[80];
char *pv;
char b[80];
int i=0;
int error=0;
pe=getenv("BLASTER");
if(pe!=NULL){
strcpy( v, pe );
pv=strpbrk(v,"A");
if(pv!=NULL){
if(debug)printf("Environment parameter BLASTER=%s\n",pv);
pv++;
i=0;
while(( *pv != '\x20' || '\x0' ) && i<80)
{
b[i]=*pv++;
i++;
}
b[i]='\x0';
i=atoi(b);
i=(i-200)/10;
psb[4]=0x200 + i*16;
}
else error=10;
pv=strpbrk(v,"I");
if(pv!=NULL){
pv++;
i=0;
while((*pv != ' ' || '\0') && i<80)
{
b[i]=*pv++;
i++;
}
b[i]='\0';
psb[1]=atoi(b);
}
else error=20;
pv=strpbrk(v,"D");
if(pv!=NULL){
pv++;
i=0;
while((*pv != ' ' || '\0') && i<80)
{
b[i]=*pv++;
i++;
}
b[i]='\0';
psb[6]=atoi(b);
}
else error=30;
pv=strpbrk(v,"T");
if(pv!=NULL){
pv++;
i=0;
while((*pv != ' ' || '\0') && i<80)
{
b[i]=*pv++;
i++;
}
b[i]='\0';
psb[7]=atoi(b);
}
else error=40;
return(error);
}
else return(-1);
}
int speaker(int state)
{
if(card_info.type==BLASTER){
_asm{
mov bx,state
mov dx,sb_address
add dx,0ch
mov cx,0ffffh
g_s: in al,dx
and al,080h
je s_ok
loop g_s
mov ax,1
jmp s_end
s_ok: cmp bx,0
je speak_off
mov al,0d1h
out dx,al
mov ax,0
jmp s_end
speak_off:
mov al,0d3h
out dx,al
mov ax,0
s_end:
}
}
}
int reset_sb(int address)
{
_asm{
mov bx,0
h0:
mov al,1
mov dx,address
add dx,6
out dx,al
in al,dx
in al,dx
in al,dx
in al,dx
mov al,0
out dx,al
add dx,4
mov cx,0ffffh
h1:
in al,dx
cmp al,0aah
je h6
loop h1
mov ax,1 ;error
jmp h3
h6:
add dx,4
mov cx,0ffffh
h4:
in al,dx
OR AL,AL
JNS H2
LOOP H4
mov ax,1 ;error
jmp h3
h5:
add bx,010h
cmp bx,050h
jle h0
mov ax,1 ;error
jmp h3
h2:
mov ax,0 ;ok
h3:
}
}
void show_card_info(void)
{
int *psb_info;
int version=0;
psb_info=&sb_info;
if(debug && (card_info.type==BLASTER))printf("Sound Blaster DSP version %X I/O %x IRQ %i DMA %i Type %i\n"
,psb_info[5],psb_info[4],psb_info[1],psb_info[6],psb_info[7]);
if(debug && card_info.type==DIGPAK){
version=get_version();
if(version==0)version=100;
printf("DIGPAK Driver version %.2f installed!\n",(float)version/100);
}
if(debug && card_info.type==PCSPEAKER)printf("No sound card found using pc speaker!\n");
}
void delay(char tc, int period)
{
if(card_info.type==BLASTER)error=sbdelay(tc,period);
}
int dacplay(char _far *fbuffer,int k,int frequency,int mode,int volume,int channels)
{
int error=0;
int flag=0;
if(card_info.type==BLASTER){
mode=(mode & 0xfffe);
switch(mode)
{
case 0:
error=sbdma(fbuffer,k,frequency,0,volume,channels);
break;
case ADPCM4:
error=sbdma(fbuffer,k,frequency,1,volume,channels);
break;
case ADPCM26:
error=sbdma(fbuffer,k,frequency,2,volume,channels);
break;
case ADPCM2:
error=sbdma(fbuffer,k,frequency,3,volume,channels);
break;
case BIT8_S:
error=sbdma(fbuffer,k,frequency,4,volume,channels);
break;
default:
if(shell)printf("\n Type of Compression not supported! \n");
else if(verbose)printf("Type of Compression not supported!\n");
multi_error=TRUE;
error=NOCOMPRESS;
break;
}
}
else if(card_info.type==DIGPAK){
snd.sound=fbuffer;
snd.sndlen=k;
snd.IsPlaying=&flag;
snd.frequency=frequency;
mode=(mode & 0xfffe);
switch(mode)
{
case 0:
case BIT8_S:
error=digplay(&snd);
break;
default:
if(shell)printf(" Type of Compression not supported!\n");
else if(verbose)printf("Type of Compression not supported!\n");
multi_error=TRUE;
error=NOCOMPRESS;
break;
}
}
return(error);
}
void show_dac_error(int error)
{
if(shell && (card_info.type!=PCSPEAKER)){
_settextcolor(14);
_settextposition(24,10);
_outtext(" ");
_settextposition(23,1);
}
if(card_info.type==BLASTER)printf("Problem with Sound Blaster ");
switch(error)
{
case 1:
printf("Error 1 DMA already in use!\n");
break;
case 2:
printf("Error 2 IRQ not responding!\n");
break;
case 3:
printf("Error 3 DSP not responding!\n");
break;
case 4:
printf("Error 4 Could not read DSP version!\n");
break;
case 5:
printf("Error 5 DMA channel not working (must be 0, 1, or 3)!\n");
break;
case 6:
printf("Error 6 I (IRQ) parameter in environment is not correct!\n");
break;
case 7:
printf("Error 7 IRQ not valid (must be 2, 3, 5, 7, or 10)!\n");
break;
case 8:
printf("Error 8 number of samples is zero!\n");
break;
case NOCOMPRESS:
break;
default:
printf("Unknown error! %i\n",error);
break;
}
}
/* Check for a Sound Card */
int get_card_type(void)
{
int type=PCSPEAKER;
if(sb_card())type=BLASTER;
if(check_digpak())type=DIGPAK;
return(type);
}
int check_digpak(void)
{
_asm{
push ds
push si
mov si,66h*4 ;get vector number
xor ax,ax ;zero
mov ds,ax ;point it there
lds si,[si] ;get address of ivec
or si,si ;zero?
jz ciout ;exit if zero
sub si,6 ;point back to identifier
cmp [si],0494dh ; 'IM' midi driver?
jne nex
cmp [si+2],04944h ;'ID' full midi driver identity string?
jne nex
; ok, a MIDI driver is loaded at this address.
mov ax,0701h ;digitized sound capabilities request
int 66h
or ax,ax
jnz dok ;yes,
jz ciout ;no
nex: cmp [si],454bh
jne ciout
cmp [si+2],4e52h
je dok
ciout: xor ax,ax ;zero driver
jmp ext
dok: mov ax,1
ext: pop si
pop ds
}
}
int get_version(void)
{
_asm{
mov bx,0
mov ax,0689h
int 66h
mov ax,bx
}
}